home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java Developer's Companion
/
Java Developer's Companion.iso
/
Javacup
/
EDUHM01H.TAR
/
education
/
EDUHM01H
/
Turing.java
< prev
next >
Wrap
Text File
|
1996-05-21
|
27KB
|
992 lines
/* This applet simulates the working of a Turing Machine. Users can */
/* run ready-made files or write their own programs. */
/* March 25 1996 */
/* Buena Vista University JAVA Team under direction of */
/* Ken Schweller schweller@bvu.edu */
import java.lang.*;
import java.io.*;
import java.awt.*;
import java.net.*;
import java.applet.*;
import java.util.*;
public class Turing extends Applet implements Runnable {
int direction;
Thread MachineThread;
int sleep_delay;
int start = 80;
int shift = 0;
boolean illegalsymbol;
Image im;
Image Turingpic;
Graphics pic;
Color bgcolor;
AudioClip loada;
AudioClip flusha;
AudioClip stepa;
AudioClip errora;
AudioClip talka;
AudioClip pressa;
AudioClip reela;
AudioClip fasta;
AudioClip overa;
AudioClip picta;
URL url;
int state;
Font picfont;
Font Tfont;
Font Tbigfont;
Font Tbiggerfont;
Font Tbigbigfont;
Font statefont;
Font Mfont;
Font bfont;
char action;
boolean done;
boolean alldone;
boolean running;
int qt = 0;
int ds[][] = new int[25][37];
char da[][] = new char[25][37];
boolean eyebrows_up;
TextField StateField;
int rot = 1;
String m1;
String message1;
String message2;
String message3;
char tape[] = new char[1000];;
char ptape[] = new char[1000];
int ptr,cs,insertpt;
int cstate;
int move_s;
char move_a;
int r;
String at;
String filename;
String line;
String legalsymbols;
TextArea rules;
char l1,l2,x,symb;
int q,j,l,s1,s2;
boolean compute_pressed;
boolean auto_pressed;
boolean reel_pressed;
char symbol[]= new char[37];
int sp;
Choice opt;
int lastrn;
String quote[][] =
{{"I believe that a Turing Machine",
"can carry out any computation",
"that any computer can!"},
{"Have you tried to program your",
"own tape for this machine? It's",
"not too hard to do. Try it!"},
{"During WW2 I worked in British",
"Intelligence trying to crack the",
"German Enigma code..."},
{"Did you know that I was a long",
"distance runner and also an",
"expert chess player?"},
{"I believe that by the end of the century",
"one will be able to speak of machines thinking",
"without expecting to be contradicted..."},
{"In 1950 I wrote an article called 'Computing Machinery",
"and Intelligence' in which I tried to answer the",
"question: Can Machines Think?"},
{"I once proposed we test whether machines can think",
"by seeing whether a blindfolded interrogator could",
"discriminate between the answers of a man and a machine."}
};
String sillyquote[] = {"Hey, that tickles!",
"Uh, Having fun with my Machine?",
"Ha ha.. getting tired of operating the Machine?",
"I see you like to click on things.. try the Tape Rollers!"};
int lastsillyrn = 3;
int hix[] = new int[5]; // position of high smoke clouds
int hiy[] = new int[5];
int hicn = -1;
int badentry = 0;
boolean badsymbol = false;
boolean isvalid(int m, char a) {
// check whether suggested move is valid
if (m == -999 || a ==0 ){
return(false);
}
else
return(true);
}
int convert(char p){
// convert symbol typed in to legal symbol
int v= -999;
if (p>64 && p < 91)
v = p - 55;
if (p>47 && p<58)
v = p - 48;
if (p== '-' || p==' ')
v = 32;
return(v);
}
void cleartape()
// erase symbols on inputoutput tape
{
int i;
for(i=0;i<1000;i++){
tape[i]=' ';
ptape[i]=' ';
}
}
void updatebuffer(){
// enter rules in rule list into state-symbol table
for (q=0; q<25; q++) /* init transition states to -999 */
for (l=0; l<37; l++){
ds[q][l]= -999;
da[q][1]= '#';
}
for (q = 0; q<37; q++)
symbol[q] = '#';
String line;
sp = -1;
String lstring;
boolean badline = false;
String buffer = rules.getText().toUpperCase();
String delim = "\n";
StringTokenizer r = new StringTokenizer(buffer,delim);
int linenum = 1;
while (r.hasMoreTokens() && !badline){
line = r.nextToken();
// parse the line into the transition matrix
StringTokenizer t = new StringTokenizer(line);
try{
s1 = Integer.valueOf(t.nextToken()).intValue();
if (s1 < 0 || s1 >36){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "State number must be between 0 and 36.";
}
lstring = t.nextToken();
if (lstring.length()>1){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "Symbol must be a single character.";
}else l1 = lstring.charAt(0);
if (convert(l1)==-999){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "Symbol must be a letter,digit, or space";
}
s2 = Integer.valueOf(t.nextToken()).intValue();
if (s2 < 0 || s2 >36){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "State number must be between 0 and 36.";
}
lstring = t.nextToken();
if (lstring.length()>1){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "Symbol must be a single character.";
}else l2 = lstring.charAt(0);
if (convert(l2)==-999 && (l2 != '<') && (l2 != '>')){
badline = true;
eyebrows_up = true;
message1 = "Loading Error in Rule #"+linenum;
message2 = "Symbol must be a letter,digit, -, <, or >";
}
}
catch (java.util.NoSuchElementException e)
{message2 = "Warning: Rule "+linenum+" is malformed...";
eyebrows_up = true;
badline = true;
}
catch (java.lang.NumberFormatException e)
{ message1 = "Loading Error in Rule #"+linenum;
message2 = "State must be a number between 0 and 36.";
eyebrows_up = true;
badline = true;
}
if (t.hasMoreTokens())
{ message1 = "Warning: Possible Error in Rule #"+linenum;
message2 = "Rule seems to have too many entries...";
eyebrows_up = true;
}
if (!badline){
store_symbol(l1);
if (l2 != '<' && l2 != '>' )
store_symbol(l2);
ds[s1][convert(l1)] = s2;
da[s1][convert(l1)] = l2;
linenum++;
}
}
rules.selectAll();
rules.replaceText(buffer,0,rules.getSelectionEnd());
}
void clear_messages(){
message1="";
message2="";
message3="";
}
void loadfile(String filename){
// load selected program file
boolean no_errors = true;
cleartape();
ptr = 500;
cs = 0;
clear_messages();
s2 = 0;
s1 = 0;
l2 = '>';
l1 = '<';
rules.selectAll();
rules.replaceText("",0,rules.getSelectionEnd());
message1 = "Opening File: "+filename;
//Attempt to Open File
DataInputStream file = null;
try
{
url = new URL(getDocumentBase(), filename);
file = new DataInputStream(url.openStream());
line = file.readLine().trim();
}
catch (java.net.MalformedURLException e)
{
message2 = "Unable to open file: Unknown URL..";
errora.play();
no_errors = false;
}
catch (java.io.IOException e)
{
message2 = "Unable to open file: "+filename;
errora.play();
no_errors = false;
}
catch(java.lang.NullPointerException e)
{
message2 = "Unable to read file: "+filename;
errora.play();
no_errors = false;
}
//read data from file
if (no_errors){
while ((line.charAt(0)=='#') && no_errors){
message2 = message3;
message3 = line;
try
{
line = file.readLine().trim();
}
catch(java.io.IOException e)
{
message2 = "Unable to read line..";
errora.play();
no_errors = false;
}
}
if (no_errors){
ptr = 500; /* load tape at position 500 */
x = 0;
while( x< line.length()){
tape[ptr++] = uppercase(line.charAt(x));
x++;
}
ptr = 500;
try
{
line = file.readLine().trim();
q = Integer.valueOf(line).intValue();
for(j=1;j<=q;j++){
line = file.readLine().trim().toUpperCase();
rules.insertText("\n",500);
rules.insertText(line,500);
}
}
catch(java.io.IOException e)
{
message2 = "Unable to read line..";
errora.play();
no_errors = false;
}
}
if (no_errors)
updatebuffer();
}
}
public void init() {
loada = getAudioClip(getCodeBase(),"load.au");
flusha = getAudioClip(getCodeBase(),"flush.au");
stepa = getAudioClip(getCodeBase(),"step.au");
errora = getAudioClip(getCodeBase(),"error.au");
talka = getAudioClip(getCodeBase(),"talk.au");
pressa = getAudioClip(getCodeBase(),"press.au");
reela = getAudioClip(getCodeBase(), "reel.au");
overa = getAudioClip(getCodeBase(), "over.au");
fasta = getAudioClip(getCodeBase(), "fast.au");
picta = getAudioClip(getCodeBase(), "stepbak.au");
Tfont = new Font("Courier", Font.PLAIN, 12);
Tbigfont = new Font("Courier", Font.BOLD, 14);
Tbiggerfont = new Font("Courier", Font.BOLD, 18);
Tbigbigfont = new Font("Courier", Font.BOLD, 20);
picfont = new Font("Times", Font.BOLD, 9);
statefont = new Font("Times", Font.BOLD, 11);
Mfont = new Font("Times", Font.ITALIC, 14);
bfont = new Font("Courier", Font.PLAIN, 1);
String at = getParameter("files");
StringTokenizer programs = new StringTokenizer(at);
im = createImage(size().width, size().height);
pic = im.getGraphics();
Turingpic = getImage(getCodeBase(), "Turing_small.gif");
eyebrows_up = false;
overa.play();
bgcolor = new Color(66,111,66);
setLayout(new BorderLayout());
Panel sp = new Panel();
add("South",sp);
sp.add(new Button("Talk"));
sp.add(new Button("Clear"));
sp.add(new Button("Stop"));
sp.add(new Button("FastAuto"));
sp.add(new Button("Auto"));
opt = new Choice();
while( programs.hasMoreTokens())
opt.addItem(programs.nextToken());
sp.add(new Button("Step"));
sp.add(new Button("Change State"));
sp.add(StateField = new TextField("0",3));
sp.add(new Button("Load"));
sp.add(opt);
sp.add(new Button("Update"));
sp.setBackground(bgcolor);
Panel ep = new Panel();
ep.setFont(bfont);
ep.setBackground(bgcolor);
add("East", ep);
rules = new TextArea(13,10);
ep.add(rules);
cleartape();
ptr = 500;
cs = 0;
done = false;
running = false;
sleep_delay = 600;
message1 = "Welcome to the Turing Machine...";
message2 = "Please click on the screen to begin. You may";
message3 = "then load a program to run or write your own!";
lastrn = 1;
repaint();
this.requestFocus();
}
void drawshadedString(String s, int x, int y, Graphics g){
// draw letters with a shadow
Color temp = g.getColor();
g.setColor(Color.black);
g.drawString(s, x+1,y+1);
g.setColor(temp);
g.drawString(s,x,y);
}
void writeMessages(Graphics g){
drawshadedString(message1,65,35,g );
drawshadedString(message2,65,50,g);
drawshadedString(message3,65,65,g );
}
boolean symbol_stored(char c){
// see if symbol has already occurred in rules
int j = 0;
while (j<20 && symbol[j] != c)
j++;
if (j<20)
return true;
else
return false;
}
void store_symbol(char c){
// store the symbol as a valid rule list symbol
if (!symbol_stored(c)){
sp = sp + 1;
symbol[sp] = c;
}
}
char uppercase(int key){
// convert symbol to legal uppercase symbol
if (key > 96 && key < 123)
return (char)(key - 32);
else if (key == '-')
return ' ';
else
return (char)key;
}
public boolean mouseDown(java.awt.Event e, int x, int y){
clear_messages();
if (x>5 && x<52 && y>4 && y<70){
// if Turings picture is clicked
if (badsymbol){
// check validity of last typed in symbol
errora.play();
message1 = "Uh, I couldn't help noticing that your previous entry";
message2 = "of '"+(char)badentry+"' does not yet appear in any rule..";
badsymbol = false;
}
else if (rules.getText().length() == 0){
// rules list must be empty
picta.play();
message1 = "I notice that you haven't loaded in any files or written";
message2 = "your own rules yet. Why not give it a try?";
}
else{
picta.play();
// return an informative Turing quote
get_silly_quote();
}
}
else if(y>167 && y<177)
// user has pressed a Tape Reel button
if (x>start-6 && x <start+9){
reela.play();
direction = '>';
reel_pressed = true;
}
else if (x>start+354 && x < start+369){
reela.play();
direction = '<';
reel_pressed = true;
}
if (x>start+15 && x<start+348 && y>147 && y<161){
// user has clicked on the tape
talka.play();
message2 = "To change tape symbols just type in what you want..";
}
else if (x>start+165 && x<start+202 && y>85 && y<130){
// user has clicked on the Turing machine black box
eyebrows_up = true;
errora.play();
message1 = "I can't show you what's inside the box. The implementation";
message2 ="of the machine is not what's really important. My theory";
message3 ="is valid even if the machine is made of rubberbands and paper clips!";
}
repaint();
return true;
}
public boolean keyDown(java.awt.Event e, int key){
clear_messages();
if (e.target == this){
// User is trying to enter new symbols on tape
illegalsymbol = false;
if (convert(uppercase(key)) == -999){
message2 = "Illegal Symbol: Symbol must be a letter, space, or digit";
illegalsymbol = true;
eyebrows_up = true;
errora.play();
repaint();
return true;
}else{
if (!symbol_stored(uppercase(key)) && (key != 32)){
// user has entered an illegal symbol
eyebrows_up = true;
badentry = uppercase(key);
badsymbol = true;
}
// add symbol to tape
tape[ptr] = uppercase(key);
pressa.play();
repaint();
return true;}
}else {
return super.keyDown(e, key);
}
}
public boolean keyUp(java.awt.Event e, int key){
if (e.target == this){
if (!illegalsymbol){
direction = '>';
reel_pressed = true;
repaint();
}
return true;
}
else
return super.keyUp(e, key);
}
public boolean action(java.awt.Event evt,Object arg ){
// A button has been pressed.. carry out action
String button= "";
running = true;
alldone = false;
done = false;
clear_messages();
this.requestFocus();
try { button = ((Button)evt.target).getLabel();}
catch(java.lang.ClassCastException e) {}
if (button == "Step"){
// make a single machine move
compute_pressed = true;
pressa.play();
repaint();
}
else if (button == "Auto"){
// continue making moves until halting
sleep_delay = 600;
auto_pressed = true;
}
else if (button == "FastAuto"){
// Fast automatic
sleep_delay = 10;
auto_pressed = true;
}
else if (button == "Stop"){
// halt automatic running
auto_pressed = false;
errora.play();
}
else if (button == "Clear"){
// clear the tape
flusha.play();
cleartape();
repaint();
}
else if (button == "Update"){
// load rule list into State-Symbol table
message2 = "Updating the Rule List...";
loada.play();
updatebuffer();
repaint();
}
else if (button == "Load"){
// load a program file
loada.play();
loadfile(opt.getSelectedItem());
repaint();
}
else if (button == "Talk"){
// let Turing spout a random saying
talka.play();
get_quote();
repaint();
}
else if (button == "Change State"){
// Change the state of the machine
cs = Integer.valueOf(StateField.getText()).intValue();
loada.play();
repaint();
}
return true;
}
public void drawwhitesquares(Graphics g, int xpos, int ypos) {
// draw white blank tape
g.setColor(Color.white);
g.fillRoundRect(xpos, ypos, 11, 18, 4, 4);
}
public void drawBox(Graphics g, int xpos, int ypos) {
// draw boxes on tape
g.setColor(Color.red);
g.drawRoundRect(xpos, ypos, 11, 18, 4, 4);
}
public void draw_machine(int start, int x, int y, Graphics g){
// draw complete Turing machaine from x start point
int xpt[] = new int[4];
int ypt[] = new int[4];
g.fill3DRect(x, y,50,50,true);
g.setColor(Color.black);
g.fill3DRect(start+175,145,13,20,true);
g.setColor(Color.white);
g.fillRect(start+177,147,9,16);
g.setFont(statefont);
drawshadedString("State", x+12,y+40,g);
g.setColor(Color.white);
g.fillRect(x+10,y+3,30,22);
g.setColor(Color.black);
g.drawRect(x+10,y+3,30,22);
Integer state = new Integer(cs);
g.setFont(Tbigbigfont);
FontMetrics fm = g.getFontMetrics();
String statestring = state.toString();
int sswidth = fm.stringWidth(statestring);
g.drawString(statestring,x+10+(30 - sswidth)/2 ,y+20);
g.setFont(Tbigfont);
StateField.setText(state.toString());
xpt[0] = x;
xpt[1] = x-20;
xpt[2] = x+30;
xpt[3] = x + 50;
ypt[0] = y;
ypt[1] = y-20;
ypt[2] = y-20;
ypt[3] = y;
//draw top of box
g.setColor(Color.lightGray);
g.fillPolygon(xpt, ypt, 4);
xpt[2] = x-20;
xpt[3] = x;
ypt[2] = y+30;
ypt[3] = y+50;
//draw smoke stack
g.setColor(Color.black);
g.fillRect(x+20, y-25, 9,15);
g.fillOval(x+20,y-21,9,15);
g.setColor(Color.white);
g.fillOval(x+20, y-28,9,5);
//draw smoke
g.setColor(Color.lightGray);
for(int k = 0; k<hicn;k++)
g.fillOval(hix[k], hiy[k],4,4);
int cn=(int)Math.floor(Math.random()*4);
hicn = cn;
for(int j=0; j<cn; j++){
int cx = x + 15 +(int)Math.floor(Math.random()*15);
int cy = y - 35 -(int)Math.floor(Math.random()*20);
g.fillOval(cx,cy,6,6);
hix[j] = cx+6;
hiy[j] = cy-20;
}
g.setColor(Color.black);
g.fillPolygon(xpt, ypt, 4);
xpt[0] = x + 10;
xpt[1] = x + 24;
xpt[2] = start+185;
xpt[3] = start+177;
ypt[0] = y + 50;
ypt[1] = y + 50;
ypt[2] = 146;
ypt[3] = 146;
g.fillPolygon(xpt,ypt,4);
}
void draw_letters(int xstart, Graphics g){
// draw letters on tape
int start = ptr-17;
int x = xstart-8;
boolean ok2draw;
g.setFont(Tfont);
for (int index = start; index < start + 35; index++){
ok2draw = true;
if (index == ptr){
g.setFont(Tbigfont);
g.drawChars(tape, index,1,x-1, 159);
g.setFont(Tfont);
ok2draw = false;
}
if (index == ptr+17){
ok2draw = false;
if (shift <=0)
g.drawChars(tape,index,1,x,157);
}
if (index == ptr-17){
ok2draw = false;
if (shift >= 0)
g.drawChars(tape, index, 1,x, 157);
}
if (ok2draw)
g.drawChars(tape,index,1, x,159);
x = x + 11;
}
}
void get_silly_quote(){
int n = (int)Math.floor(Math.random()*4);
while (n == lastsillyrn)
n = (int)Math.floor(Math.random()*4);
lastsillyrn = n;
clear_messages();
message2 = sillyquote[n];
}
void get_quote(){
// get informative quote
int n = (int)Math.floor(Math.random()*7);
while (n == lastrn)
n = (int)Math.floor(Math.random()*7);
lastrn = n;
message1 = quote[n][0];
message2 = quote[n][1];
message3 = quote[n][2];
}
void draw_spokes(int start, Graphics g){
// draw spokes in tape reel
int spoke[][] = {{0,-4},{12,0},{0,+4},{-12,0}};
if (rot>3) rot = 0;
if (rot<0) rot = 3;
g.setColor(Color.black);
g.drawLine(start+2,131, start+2+spoke[rot][0], 131+spoke[rot][1]);
g.drawLine(start+362,131, start+362+spoke[rot][0], 131+spoke[rot][1]);
}
void draw_reels(int start,Graphics g){
g.setColor(Color.black);
g.fillRect(start-11,130,25,50);
g.fillRect(start+349,130,25,50);
g.fillOval(start-11,176,25,9);
g.fillOval(start+349,176,25,9);
g.setColor(Color.white);
int xb[] = {start-6,start+9,start+9};
int yb[] = {172,167,177};
g.fillPolygon(xb,yb,3);
xb[0] = start+369;
xb[1] = start+354;
xb[2] = start+354;
g.fillPolygon(xb,yb,3);
int xpt[]= {start-11,start+shift,start+shift,start-11};
int ypt[]= {142,145,163,160};
g.fillPolygon(xpt, ypt, 4);
g.setColor(Color.red);
g.drawPolygon(xpt,ypt,4);
g.setColor(Color.white);
xpt[0] = start+shift+363;
xpt[1]=start+374;
xpt[2]=start+374;
xpt[3]=start+shift+363;
ypt[0] = 145;
ypt[1] = 142;
ypt[2] = 160;
ypt[3] = 163;
g.fillPolygon(xpt,ypt,4);
g.setColor(Color.red);
g.drawPolygon(xpt,ypt,4);
g.setColor(Color.white);
g.fillOval(start-11,126,25,9);
g.fillOval(start+349,126,25,9);
draw_spokes(start,g);
}
public void paintPIC(Graphics g){
// offscreen graphic
Dimension r = size();
g.clearRect(0,0,r.width, r.height);
g.setColor(bgcolor);
g.fillRect(0,0,r.width, r.height);
draw_reels(start,g);
// draw the tape
for(int i=start+shift; i<start+shift+363; i+=11)
drawwhitesquares(g,i,145);
for(int i=start+shift; i<start+shift+363; i+=11)
drawBox(g,i,145);
g.setColor(Color.red);
int boxx = start+163 +(int)Math.floor(Math.random()*8);
int boxy = 83 +(int)Math.floor(Math.random()*10);
// draw rest of machine
draw_machine(start,boxx, boxy, g);
g.setColor(Color.black);
draw_letters(start+shift,g);
g.setColor(Color.black);
g.setFont(statefont);
// add picture of Turing
g.drawRect(4,4,50,60);
g.drawString("Alan Turing",5,88);
g.drawString("1912 - 1954",5,100);
g.fillRect(2,2,56,73);
g.drawImage(Turingpic, 10, 5, this);
if (eyebrows_up){
g.drawLine(38,24,44,27);
g.drawLine(46,27,49,24);
eyebrows_up = false;
}
// see if done
if (done) {
g.setColor(Color.red);
message1 ="Computation HALTED...";
if (!symbol_stored(uppercase(tape[ptr])) && (tape[ptr] != 32)){
message2 = " Unrecognized symbol on tape...";
errora.play();
}
else{
message2 = " I think we might be done because";
message3 = " I have no rule for this situation...";
overa.play();
}
alldone = true;
done = false;
}
// add messages and labels
g.setFont(statefont);
g.setColor(Color.yellow);
writeMessages(g);
g.setColor(Color.black);
g.setFont(Tbiggerfont);
g.setColor(Color.red);
drawshadedString("Ye Olde Turing Machine",160,19,g);
g.setFont(statefont);
g.setColor(Color.white);
drawshadedString("Input/Output Tape",start+50, 180,g);
drawshadedString("<= Turing Machine", start+222, 110,g);
drawshadedString("Rule List =>", r.width-175,80,g);
}
public void paint(Graphics g) {
// paint to screen
paintPIC(pic);
g.drawImage(im,0,0,null);
}
public void start(){
// new thread for automatic running of machine
MachineThread = new Thread(this);
MachineThread.start();
requestFocus();
}
public void run(){
// run machine as long as auto_pressed is on
int timer = 0;
while (MachineThread != null) {
try {Thread.sleep(sleep_delay);}
catch(InterruptedException e) {}
if (auto_pressed){
if (timer++%100 == 0){
fasta.play();
}
compute_pressed=true;
repaint();
}
}
repaint();
}
public void update(Graphics g){
if (reel_pressed){
// advance or retract tape
switch(direction) {
case '>':
rot++;
shift = -5;
paint(g);
rot++;
ptr++;
shift = 0;
break;
case '<':
rot--;
shift = 5;
paint(g);
rot--;
ptr--;
shift = 0;
break;
}
paint(g);
reel_pressed = false;
}else
if (shift==0){
// calculate new move
if (running && compute_pressed){
int ts = convert(tape[ptr]);
if (ts != -999){
move_s = ds[cs][convert(tape[ptr])];
move_a = da[cs][convert(tape[ptr])];
ptape[ptr]=' ';
if (isvalid(move_s,move_a)){
// update machine to reflect new move
cs = move_s;
action = uppercase(move_a);
stepa.play();
switch(action) {
case '>':
rot++;
shift = -5;
paint(g);
rot++;
ptr++;
shift = 0;
break;
case '<':
rot--;
shift = 5;
paint(g);
rot--;
ptr--;
shift = 0;
break;
default:{
tape[ptr] = action;
}
}
}
else{
done = true;
auto_pressed = false;
}
}
}
compute_pressed = false;
paint(g);
}
}
public void computethis()
// compute new move
{
if (running && compute_pressed){
int ts = convert(tape[ptr]);
if (ts != -999){
move_s = ds[cs][convert(tape[ptr])];
move_a = da[cs][convert(tape[ptr])];
ptape[ptr]=' ';
if (isvalid(move_s,move_a)){
cs = move_s;
action = uppercase(move_a);
switch(action) {
case '>': ptr++;
rot++;
break;
case '<': ptr--;
rot--;
break;
default:{
tape[ptr] = action;
}
}
}
else
done = true;
}
}
repaint();
}
}